home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / gfx / show / gs503_data.lha / Ghostscript / data / pdf_font.ps < prev    next >
Text File  |  1997-08-14  |  14KB  |  437 lines

  1. %    Copyright (C) 1994, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % pdf_font.ps
  16. % PDF font operations.
  17.  
  18. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  19. .currentglobal true .setglobal
  20. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  21. GS_PDF_ProcSet begin
  22. pdfdict begin
  23.  
  24. % We cache the PostScript font in an additional element of the
  25. % font resource dictionary, called PSFont.
  26.  
  27. % ---------------- Encodings ---------------- %
  28.  
  29. % Apply a list of differences to an Encoding.
  30. /updateencoding        % <encoding> <differences> updateencoding <enc'>
  31.  { exch dup length array copy
  32.    exch dup 0 get exch dup length 1 sub
  33.    1 exch getinterval
  34.     { dup type /nametype ne
  35.        { exch pop }
  36.        { 3 copy put pop 1 add }
  37.       ifelse
  38.     }
  39.    forall pop
  40.  } bdef
  41.  
  42. % Get the Encoding for a font.
  43. /getencoding        % <base-encoding> <font-resource> getencoding <enc>
  44.  { /Encoding knownoget
  45.     { dup type /nametype eq
  46.        { exch pop findencoding
  47.        }
  48.        { dup /BaseEncoding knownoget
  49.       { findencoding 3 -1 roll pop exch
  50.       }
  51.      if
  52.      /Differences knownoget { updateencoding } if
  53.        }
  54.       ifelse
  55.     }
  56.    if
  57.  } bdef
  58.  
  59. % Adjust a font according to the Encoding and Widths in the font resource.
  60. /adjustfont        % <font-resource> <font> adjustfont
  61.             %   <font'> <changed>
  62.  { getfontencoding getfontmetrics 4 -1 roll pop .updatefont
  63.     { dup /FontName 2 copy get genfontname dup 5 1 roll put definefont }
  64.    if
  65.  } bind def
  66.  
  67. % Get the (possibly modified) encoding of a font.
  68. /getfontencoding    % <font-resource> <font> getfontencoding
  69.             %   <font-resource> <font> <encoding>
  70.  { dup /Encoding get 2 index getencoding
  71.  } bdef
  72.  
  73. % Get the metrics of a font, if specified.
  74. /getfontmetrics        % <font-resource> <font> <encoding> getfontmetrics
  75.             %   <font-resource> <font> <encoding> <Metrics|null>
  76.  { 2 index /Widths known
  77.     { 2 dict begin
  78.       /Encoding exch def
  79.       /Metrics Encoding length dict def
  80.       exch
  81.         % Stack: font font-res
  82.         % Note that widths are always based on a 1000-unit
  83.         % character space, but the FontMatrix may specify
  84.         % some other scale factor.  Compensate for this here,
  85.         % by scaling the Widths if necessary.
  86.       0.001 2 index /FontMatrix get 0 get div
  87.         % Stack: font font-res mscale
  88.       1 index /FirstChar oget dup 1 4 index /LastChar oget
  89.        {    % Stack: font font-res mscale first-char index
  90.      Encoding 1 index get
  91.      4 index /Widths oget 2 index 4 index sub get
  92.          % Stack: font font-res mscale first-char index charname width
  93.      4 index mul
  94.         % There is a hack here to deal with encodings where the
  95.         % same character appears more than once, because the Metrics
  96.         % dictionary works by character name, not by character code.
  97.         % Because of this, we can't deal with Width vectors that
  98.         % specify different widths for the same character name
  99.         % appearing multiple times in the Encoding.
  100.      Metrics 2 index .knownget not { 0 } if 0 ne
  101.       { pop pop }
  102.       { Metrics 3 1 roll put }
  103.      ifelse pop
  104.        }
  105.       for pop
  106.         % Now fill in the MissingWidth for any encoded characters
  107.         % that aren't in Metrics already.
  108.         % Stack: font font-res mscale
  109.       Metrics 2 index /FontDescriptor oget
  110.       /MissingWidth knownoget { 2 index mul } { 0 } ifelse exch
  111.       Encoding
  112.        {    % Stack: font font-res mscale missing-width metrics charname
  113.      2 copy known not { 2 copy 4 index put } if pop
  114.        }
  115.       forall pop pop pop
  116.       exch Encoding Metrics end
  117.     }
  118.     { null
  119.     }
  120.    ifelse
  121.  } bdef
  122.  
  123. % ---------------- Descriptors ---------------- %
  124.  
  125. % Partial descriptors for the 14 built-in fonts.
  126. /standardfontdescriptors mark
  127.   /Courier mark /Flags 16#23 .dicttomark
  128.   /Courier-Oblique 1 index
  129.   /Courier-Bold 1 index
  130.   /Courier-BoldOblique 1 index
  131.   /Helvetica mark /Flags 16#20 .dicttomark
  132.   /Helvetica-Oblique 1 index
  133.   /Helvetica-Bold 1 index
  134.   /Helvetica-BoldOblique 1 index
  135.   /Times-Roman mark /Flags 16#22 .dicttomark
  136.   /Times-Bold 1 index
  137.   /Times-Italic mark /Flags 16#62 .dicttomark
  138.   /Times-BoldItalic 1 index
  139.   /Symbol mark /Flags 16#4 .dicttomark
  140.   /ZapfDingbats 1 index
  141. .dicttomark readonly def
  142.  
  143. % ---------------- Utilities ---------------- %
  144.  
  145. % Fabricate a font name by adding %'s on the end.
  146. /genfontname        % <name> genfontname <name>
  147.  { dup length string cvs
  148.     { (%) concatstrings
  149.       dup cvn FontDirectory exch known not { cvn exit } if
  150.     }
  151.    loop
  152.  } bdef
  153.  
  154. % Find a font, and adjust its encoding if necessary.
  155. /pdffindfont        % <font-resource> <fontname> pdffindfont <font>
  156.  { findfont adjustfont
  157.  } bdef
  158.  
  159. % ---------------- Type 1 fonts ---------------- %
  160.  
  161. /buildType1        % <Type1-font-resource> buildType1 <font>
  162.  { dup /BaseFont get pdffindfont
  163.  } bdef
  164.  
  165. % The state dictionary for the embedded Type 1 font reading procedure
  166. % has the following keys and values:
  167. %    data - stream (filter)
  168. %    buffer, buffer2 - string
  169. %    leftstr - string containing (non-negative) integer
  170. %    sectionstr - string containing a character 0 .. 2
  171. %    stream - (stream) dictionary
  172. %    proc - procedure of the form {-dict- type1read}
  173. % When the procedure is executing, this dictionary is current.
  174. % leftstr and sectionstr are strings so that we can change their values
  175. % reliably in case the font executes a restore!
  176.  
  177. % Read an embedded Type 1 font.
  178. /readfontfilter        % <proc> readfontfilter <filter>
  179.  {    % We make this a separate procedure so that we can
  180.     % redefine it when we're writing PostScript.
  181.    0 () /SubFileDecode filter
  182.  } bdef
  183. /readtype1        % <font-resource> <stream-dict> readtype1 <font>
  184.  {        % Read the definition, using a procedure-based filter
  185.         % that turns binary/hex conversion on and off
  186.         % at the right times.
  187.    PDFfile fileposition 3 1 roll
  188.    7 dict begin
  189.      /leftstr (          ) 10 string copy def
  190.        dup /Length1 oget leftstr cvs pop
  191.      /sectionstr <00> 1 string copy def
  192.      /stream 1 index def
  193.      true resolvestream /data exch def
  194.      /buffer 1000 string def        % arbitrary
  195.      /buffer2 buffer length 2.1 div cvi 1 sub string def
  196.    currentdict end
  197.    /type1read cvx 2 array astore cvx dup 0 get /proc 2 index put
  198.    readfontfilter
  199.         % Some buggy embedded fonts leave extra junk on the stack,
  200.         % so we have to make a closure that records the stack depth
  201.         % in a fail-safe way.
  202.    //systemdict begin
  203.     { run } aload pop count 1 sub 2 packedarray cvx exec
  204.    end
  205.    count exch sub { pop } repeat
  206.    PDFfile 3 -1 roll setfileposition
  207.    /FontDescriptor oget /FontName oget findfont
  208.  } bdef
  209.  
  210. % Execute the appropriate reading procedure.
  211. /type1read        % <dict> type1read <string>
  212.  { begin leftstr cvi
  213.     { type1read1 type1read2 type1read3 } sectionstr 0 get get exec
  214.    (          ) leftstr copy cvs pop end
  215.  } bdef
  216.  
  217. % Read the next block of data into the buffer.
  218. /type1readdata        % <left> <buffer> type1readdata <substring> <left'>
  219.  { 0 2 index 2 index length min getinterval
  220.         % Adobe requires readstring to signal an error if given
  221.         % an empty string.  Work around this nonsense here.
  222.    dup length 0 ne { data exch readstring pop } if
  223.    dup length 3 -1 roll exch sub
  224.    DEBUG
  225.     { dup =only ( read ) print
  226.       1 index length =only (: ) print
  227.       1 index == flush
  228.     } if
  229.  } bdef
  230.  
  231. % Read the next block of the initial text portion.
  232. /type1read1        % <left> type1read1 <string> <left'>
  233.  { DEBUG { (read1 ) print } if
  234.    dup 0 eq
  235.     { pop sectionstr 0 1 put
  236.       stream /Length2 oget type1read2
  237.     }
  238.     { buffer type1readdata
  239.     }
  240.    ifelse
  241.  } bdef
  242.  
  243. % Read the next block of the encrypted portion.
  244. /type1trailer
  245. (0000000000000000000000000000000000000000000000000000000000000000\n\
  246. 0000000000000000000000000000000000000000000000000000000000000000\n\
  247. 0000000000000000000000000000000000000000000000000000000000000000\n\
  248. 0000000000000000000000000000000000000000000000000000000000000000\n\
  249. 0000000000000000000000000000000000000000000000000000000000000000\n\
  250. 0000000000000000000000000000000000000000000000000000000000000000\n\
  251. 0000000000000000000000000000000000000000000000000000000000000000\n\
  252. 0000000000000000000000000000000000000000000000000000000000000000\n\
  253. cleartomark\n)
  254. readonly def
  255. /type1read2        % <left> type1read2 <string> <left'>
  256.  { DEBUG { (read2 ) print } if
  257.    dup 0 eq
  258.     { pop sectionstr 0 2 put
  259.       stream /Length3 oget
  260.       dup 0 eq
  261.        { DEBUG { (trailer ) print } if
  262.      type1trailer exch
  263.        }
  264.        { type1read3
  265.        }
  266.       ifelse
  267.     }
  268.     { buffer2 type1readdata exch
  269.       buffer /ASCIIHexEncode filter dup 3 -1 roll writestring closefile
  270.       buffer (>) search pop exch pop exch pop exch
  271.     }
  272.    ifelse
  273.  } bdef
  274.  
  275. % Read the next block of the final text portion.
  276. % When finished, this procedure returns an empty string.
  277. /type1read3        % <left> type1read3 <string> <left'>
  278.  { DEBUG { (read3 ) print } if
  279.    buffer type1readdata
  280.  } bdef
  281.  
  282. % ---------------- Type 3 fonts ---------------- %
  283.  
  284. /.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
  285.  
  286. /buildType3        % <Type3-font-resource> buildType3 <font>
  287.   { 8 dict begin
  288.     /FontType 3 def
  289.     /FontBBox 1 index /FontBBox get cvx def
  290.     /FontMatrix 1 index /FontMatrix oget def
  291.     /CharProcs 1 index /CharProcs oget def
  292.     /FontName 1 index /Name get genfontname def
  293.     /Encoding .notdefEncoding 2 index getencoding def
  294.     /BuildGlyph
  295.      { exch /CharProcs get exch oget
  296.        PDFfile fileposition exch
  297.        false resolvestream
  298.         % Don't let setgcolor set the color inside the BuildGlyph
  299.         % procedure, because this causes an /undefined error.
  300.        q_ null /FillColor gput null /StrokeColor gput
  301.        pdfopdict .pdfrun
  302.        Q_
  303.        PDFfile exch setfileposition
  304.      } bdef
  305.     FontName currentdict end definefont exch pop
  306.   } bdef
  307.  
  308. % ---------------- TrueType fonts ---------------- %
  309.  
  310. /TTfonts mark
  311.   /Arial /Helvetica
  312.   /Arial,Italic /Helvetica-Oblique
  313.   /Arial,Bold /Helvetica-Bold
  314.   /Arial,BoldItalic /Helvetica-BoldOblique
  315.   /TimesNewRoman /Times-Roman
  316.   /TimesNewRoman,Italic /Times-Italic
  317.   /TimesNewRoman,Bold /Times-Bold
  318.   /TimesNewRoman,BoldItalic /Times-BoldItalic
  319. .dicttomark readonly def
  320.  
  321. /buildTrueType        % <TrueType-font-resource> buildTrueType <font>
  322.  { dup /BaseFont get
  323.    dup TTfonts exch .knownget { exch pop } if pdffindfont
  324.  } bdef
  325.  
  326. % Read an embedded TrueType font.
  327. /readtruetype        % <font-resource> <stream-dict> readtruetype <font>
  328.  {        % This is much simpler than readtype1, because we don't
  329.         % have to deal with the tripartite .PFB format.
  330.    PDFfile fileposition 3 1 roll
  331.    true resolvestream readfontfilter .loadttfont
  332.    dup /FontName get exch definefont exch pop
  333.    PDFfile 3 -1 roll setfileposition
  334.  } bdef
  335.  
  336. % ---------------- Type 0 fonts ---------------- %
  337. %**************** NOT ACTUALLY SUPPORTED YET
  338.  
  339. /buildType0        % <Type0-font-resource> buildType0 <font>
  340. { 10 dict begin
  341.   /FontType 0 def
  342.   /FontMatrix 1 index /FontMatrix knownoget not { matrix } if def
  343.   /FontName 1 index /BaseFont get def
  344.   /FMapType 9 def
  345.   /Encoding [ 0 1 4 index /DescendantFonts oget length 1 sub { } for ] def
  346.   /FDepVector [ 2 index /DescendantFonts oget { exec } forall ] def
  347.   /CMap 1 index /Encoding oget
  348.     dup type /nametype eq
  349.      { dup Page /CMap rget
  350.         { exch pop resolvestream } { /undefined signalerror } ifelse
  351.      }
  352.      { resolvestream
  353.      }
  354.     ifelse
  355.   % FontName currentdict end definefont exch pop
  356.   end pop /Times-Roman findfont
  357. } bdef
  358.  
  359. % ---------------- Other embedded fonts ---------------- %
  360.  
  361. /fontloadprocs mark
  362.   /Type1C /readType1C cvx
  363. .dicttomark readonly def
  364.  
  365. % Read an embedded compressed font.
  366. /readType1C        % <font-resource> <stream-dict> readType1C <font>
  367.  { PDFfile fileposition 3 1 roll
  368.    dup true resolvestream dup readfontfilter
  369.         % Stack: pos resource streamdict stream filter
  370.    3 index /FontDescriptor oget /FontName oget
  371.    1 index FRD
  372.    closefile closefile pop
  373.    PDFfile 3 -1 roll setfileposition
  374.    /FontDescriptor oget /FontName oget findfont
  375.  } bdef
  376.  
  377. % ---------------- Font lookup ---------------- %
  378.  
  379. /fonttypeprocs mark        % <font-resource> -proc- <font>
  380.   /Type0 /buildType0 cvx
  381.   /Type1 /buildType1 cvx
  382.   /MMType1 1 index
  383.   /Type3 /buildType3 cvx
  384.   /TrueType /buildTrueType cvx
  385. .dicttomark readonly def
  386.  
  387. /resourcefont            % <font-resource> resourcefont <font>
  388.  { dup /PSFont .knownget
  389.     { /FID .knownget { type /fonttype eq } { false } ifelse }
  390.     { false }
  391.    ifelse
  392.     { /PSFont get
  393.     }
  394.     { dup dup /FontDescriptor knownoget
  395.        {    % Stack: font-res font-res font-desc
  396.      dup /FontFile knownoget
  397.       { exch pop 1 index 3 1 roll readtype1 adjustfont true }
  398.       { dup /FontFile2 knownoget
  399.          { exch pop 1 index 3 1 roll readtruetype adjustfont true }
  400.          { /FontFile3 knownoget
  401.         { 1 index exch dup /Subtype get fontloadprocs exch get exec adjustfont true }
  402.         { false }
  403.            ifelse
  404.          }
  405.         ifelse
  406.       }
  407.      ifelse
  408.        }
  409.        { false }
  410.       ifelse
  411.         % Stack: font-res font-res false
  412.         %  -or-: font-res font true
  413.       not
  414.        { dup /Subtype get fonttypeprocs exch get exec }
  415.       if
  416.       2 copy /PSFont exch put
  417.       exch pop
  418.     }
  419.    ifelse
  420.  } bdef
  421.  
  422. drawopdict begin
  423.   /d0 /setcharwidth load def
  424.   /d1 /setcachedevice load def
  425.   /Tf
  426.    { exch Page /Resources oget /Font oget exch oget resourcefont
  427.      exch Tf
  428.    } bdef
  429. end
  430.  
  431. end            % pdfdict
  432. end            % GS_PDF_ProcSet
  433. .setglobal
  434.